package web

import (
	"errors"
	"fmt"
	errors2 "gitee.com/lipore/plume/errors"
	"net/http"
)

type HttpError struct {
	StatusCode int
	Message    string
}

func (e *HttpError) Error() string {
	return e.Message
}

func HandleHttpError(err error) {
	if err != nil {
		panic(err)
	}
}
func HandleHttpErrorWithStatusCode(stateCode int, err error, message string) {
	if err != nil {
		if message != "" {
			panic(HttpError{StatusCode: stateCode, Message: message})
		}
		panic(HttpError{StatusCode: stateCode, Message: http.StatusText(stateCode)})
	}
}
func HandleBadRequest(err error) {
	HandleHttpErrorWithStatusCode(http.StatusBadRequest, err, "")
}
func HandleServerError(err error) {
	HandleHttpErrorWithStatusCode(http.StatusInternalServerError, err, "")
}
func HandleNotFound(err error, message string) {
	HandleHttpErrorWithStatusCode(http.StatusNotFound, err, message)
}
func HandleUnauthorized(err error, message string) {
	HandleHttpErrorWithStatusCode(http.StatusUnauthorized, err, message)
}
func HandleNoPermission(err error, message string) {
	HandleHttpErrorWithStatusCode(http.StatusForbidden, err, message)
}
func HandleMethodNotAllow(r *http.Request) {
	HandleHttpErrorWithStatusCode(
		http.StatusMethodNotAllowed,
		errors.New(http.StatusText(http.StatusMethodNotAllowed)),
		fmt.Sprintf("method: %s are not allowed on %s", r.Method, r.URL.Path),
	)
}
func ErrorHandlerMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			re := recover()
			if re != nil {
				if err, isError := re.(error); isError {
					if httpError, ok := err.(*HttpError); ok {
						http.Error(w, httpError.Error(), httpError.StatusCode)
						return
					}
					coder := errors2.ParseCoder(err)
					http.Error(w, coder.String(), coder.HTTPStatus())
				}

				http.Error(w, "server internal error", http.StatusInternalServerError)
			}
		}()
		next.ServeHTTP(w, r)
	})
}
